/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SLE_SSAP_CLIENT_HAL_H
#define SLE_SSAP_CLIENT_HAL_H

#ifndef SLE_LOG_TAG
#define SLE_LOG_TAG "[SleHal]"
#endif

#include "sle_ssap_client_hdi.h"
#include "sle_ssap_config.h"
#include "sle_ssap_client_config.h"
#include "sle_hal_errcode.h"
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief   Callback for structure found
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] service
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalFindStructureCallback)(uint8_t clientId, uint16_t connectId, const ClientFindServiceRes *service, SleHalErrorCode errCode);

/**
 * @brief   Callback for property found
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] property
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalFindPropertyCallback)(uint8_t clientId, uint16_t connectId, const ClientFindPropertyRes *property, SleHalErrorCode errCode);

/**
 * @brief   Callback for find complete
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] data
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalCompleteFindStructureCallback)(uint8_t clientId, uint16_t connectId, const ClientFindStructureRes *structureResult, SleHalErrorCode errCode);

/**
 * @brief   Callback for receive read response
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] data
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalReceiveReadResponseCallback)(uint8_t clientId, uint16_t connectId, const ClientHandleValue *readData, SleHalErrorCode errCode);

/**
 * @brief   Callback for read feature complete
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] data
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalReadByUUidCallback)(uint8_t clientId, uint16_t connectId, const ClientReadByUuidCmpRes *cmpResult, SleHalErrorCode errCode);

/**
 * @brief   Callback for receive write response
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] data
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalReceiveWriteResponseCallback)(uint8_t clientId, uint16_t connectId, const ClientWriteRes *writeResult, SleHalErrorCode errCode);

/**
 * @brief   Callback for receive exchange information response
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] data
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalReceiveExchangeInfoResponseCallback)(uint8_t clientId, uint16_t connectId, const SsapMtuInfo *param, SleHalErrorCode errCode);

/**
 * @brief   Callback for receive notification
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] data
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalReceiveNotificationCallback)(uint8_t clientId, uint16_t connectId, const ClientHandleValue *data, SleHalErrorCode errCode);

/**
 * @brief   Callback for receive indication
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] data
 * @param   [in] errCode
 * @return  None
 */
typedef void (*SleHalReceiveIndicationCallback)(uint8_t clientId, uint16_t connectId, const ClientHandleValue *data, SleHalErrorCode errCode);

typedef struct {
    SleHalFindStructureCallback OnSsapcStructFoundCb;
    SleHalFindPropertyCallback OnSsapcPropertyFoundCb;
    SleHalCompleteFindStructureCallback OnSsapcFindStructDoneCb;
    SleHalReceiveReadResponseCallback OnSsapcRecvReadRespCb;
    SleHalReadByUUidCallback OnSsapcReadByUuidCb;
    SleHalReceiveWriteResponseCallback OnSsapcRecvWriteRespCb;
    SleHalReceiveExchangeInfoResponseCallback OnSsapcRecvExchangeInfoRespCb;
    SleHalReceiveNotificationCallback OnSsapcRecvNotificationCb;
    SleHalReceiveIndicationCallback OnSsapcRecvIndicationCb;
} SleSsapcHalCallbacks;

/**
 * @brief   Initialize the SLE SSAPC HAL
 * 
 * @param   None
 * @return  SleHalErrorCode
 */ 
SleHalErrorCode InitSleSsapcHal(void);

/**
 * @brief   Deinitialize the SLE SSAPC HAL
 * 
 * @param   None
 * @return  SleHalErrorCode
 */
SleHalErrorCode DeinitSleSsapcHal(void);

/**
 * @brief   Add a clien
 * 
 * @param   [in] appUuid
 * @param   [out] clientId
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalAddClient(const SleUuid *appUuid, uint8_t *clientId);

/**
 * @brief   Remove a client
 *
 * @param   [in] clientId
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalRemoveClient(uint8_t clientId);

/**
 * @brief   Find a service by UUID
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] paramFind
 * @return  SleHalErrorCode
 * 
 * @note    oprate result @link SleHalCompleteFindStructureCallback
 */
SleHalErrorCode SleSsapcHalFindStructure(uint8_t clientId, uint16_t connectId, const ClientFindStructure *paramFind);

/**
 * @brief   Find a property by UUID
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] paramFind
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalReadReqByUuid(uint8_t clientId, uint16_t connectId, const ClientReadReqByUUID *paramRead);

/**
 * @brief   Read a property by handle
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] handle
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalReadReq(uint8_t clientId, uint16_t connectId, uint16_t handle, SleSsapPropertyType propertyTpye);

/**
 * @brief   Write a property by handle
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] paramWrite
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalWriteReq(uint8_t clientId, uint16_t connectId, const ClientWriteParam *paramWrite);

/**
 * @brief   Exchange information with the server
 * 
 * @param   [in] clientId
 * @param   [in] connectId
 * @param   [in] paramExchange
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalWriteCmd(uint8_t clientId, uint16_t connectId, const ClientWriteParam *paramWrite);

/**
 * @brief   Register callbacks
 * 
 * @param   [in] clientId
 * @param   [in] callback
 * @param   [in] paramExchange
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalExchangeInfoReq(uint8_t clientId, uint16_t connectId,const SsapMtuInfo* paramExchange);

/**
 * @brief   Register callbacks
 * 
 * @param   [in] callback
 * @return  SleHalErrorCode
 */
SleHalErrorCode SleSsapcHalRegisterCallbacks(const SleSsapcHalCallbacks *callback);
#ifdef __cplusplus
}
#endif

#endif //SLE_SSAP_CLIENT_HAL_H
